home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
The World of Computer Software.iso
/
ply15dat.zip
/
BALLS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-19
|
6KB
|
182 lines
/*
* balls.c - Create a set of shiny spheres, with each sphere blooming sets of
* 9 more spheres with 1/3rd radius. None of the spheres are clipped. A
* square floor polygon is added. Three light sources.
*
* Version: 2.2 (11/17/87)
* Author: Eric Haines, 3D/Eye, Inc.
*
* SIZE_FACTOR determines the number of objects output.
* Total spheres = sum of n=0,SF of (9**SF).
*
* SIZE_FACTOR # spheres # squares
* 1 10 1
* 2 91 1
* 3 820 1
*
* 4 7381 1
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "def.h"
#include "lib.h"
#define OUTPUT_FORMAT OUTPUT_CURVES
#define SIZE_FACTOR 3
static COORD4 objset[9];
/*
* Output the parent sphere, then output the children of the sphere.
* Uses global 'objset'.
*/
void
output_objset(long depth, COORD4 *center, COORD4 *direction)
{
double angle;
COORD4 axis, z_axis;
COORD4 child_pt, child_dir;
MATRIX mx;
long num_vert;
double scale;
/* output sphere at location & radius defined by center */
lib_output_sphere(center, OUTPUT_CURVES);
/* check if children should be generated */
if ( depth > 0 ) {
--depth ;
/* rotation matrix to new axis from +Z axis */
if ( direction->z >= 1.0 ) {
/* identity matrix */
lib_create_identity_matrix( mx ) ;
}
else if ( direction->z <= -1.0 ) {
lib_create_rotate_matrix( mx, Y_AXIS, PI ) ;
}
else {
SET_COORD( z_axis, 0.0, 0.0, 1.0 ) ;
CROSS( axis, z_axis, (*direction) ) ;
lib_normalize_coord3( &axis ) ;
angle = acos( (double)DOT_PRODUCT( z_axis, (*direction) ) ) ;
lib_create_axis_rotate_matrix( mx, &axis, angle ) ;
}
/* scale down location of new spheres */
scale = center->w * (1.0 + direction->w ) ;
for ( num_vert = 0 ; num_vert < 9 ; ++num_vert ) {
lib_transform_coord( &child_pt, &objset[num_vert], mx ) ;
child_pt.x = child_pt.x * scale + center->x ;
child_pt.y = child_pt.y * scale + center->y ;
child_pt.z = child_pt.z * scale + center->z ;
/* scale down radius */
child_pt.w = center->w * direction->w ;
SUB3_COORD( child_dir, child_pt, (*center) ) ;
child_dir.x /= scale ;
child_dir.y /= scale ;
child_dir.z /= scale ;
child_dir.w = direction->w ;
output_objset(depth, &child_pt, &child_dir);
}
}
}
/* Create the set of 9 vectors needed to generate the sphere set. */
/* Uses global 'objset' */
void
create_objset()
{
COORD4 axis, temp_pt, trio_dir[3] ;
double dist ;
MATRIX mx ;
long num_set, num_vert ;
dist = 1.0 / sqrt( (double)2.0 ) ;
SET_COORD4( trio_dir[0], dist, dist, 0.0, 0.0 ) ;
SET_COORD4( trio_dir[1], dist, 0.0, -dist, 0.0 ) ;
SET_COORD4( trio_dir[2], 0.0, dist, -dist, 0.0 ) ;
SET_COORD( axis, 1.0, -1.0, 0.0 ) ;
lib_normalize_coord3( &axis ) ;
lib_create_axis_rotate_matrix(
mx,
&axis,
asin( (double) ( 2.0 / sqrt( (double)6.0 ) ) ) ) ;
for ( num_vert = 0 ; num_vert < 3 ; ++num_vert ) {
lib_transform_coord( &temp_pt, &trio_dir[num_vert], mx ) ;
COPY_COORD( trio_dir[num_vert], temp_pt ) ;
}
for ( num_set = 0 ; num_set < 3 ; ++num_set ) {
lib_create_rotate_matrix( mx, Z_AXIS, num_set*2.0*PI/3.0 ) ;
for ( num_vert = 0 ; num_vert < 3 ; ++num_vert ) {
lib_transform_coord( &objset[num_set*3+num_vert],
&trio_dir[num_vert], mx ) ;
}
}
}
void
main(int argc, char *argv[])
{
COORD4 back_color, obj_color ;
COORD4 backg[4], bvec, light ;
COORD4 from, at, up, dir;
COORD4 center_pt, direction ;
double radius ;
/* We are using Polyray */
lib_set_raytracer(OUTPUT_POLYRAY);
/* set radius of sphere which would enclose entire object */
radius = 1.0 ;
/* output viewpoint */
SET_COORD( from, 2.1, 1.3, 1.7 ) ;
SET_COORD( at, 0.0, 0.0, 0.0 ) ;
SET_COORD( up, 0.0, 0.0, 1.0 ) ;
lib_output_viewpoint( &from, &at, &up, 45.0, 1.0, 1.0, 256, 256);
/* output background color - UNC sky blue */
SET_COORD( back_color, 0.078, 0.361, 0.753 ) ;
lib_output_background_color( &back_color ) ;
/* output light sources */
SET_COORD4( light, 4.0, 3.0, 2.0, 0.6 ) ;
lib_output_light( &light ) ;
SET_COORD4( light, 1.0, -4.0, 4.0, 0.6 ) ;
lib_output_light( &light ) ;
SET_COORD4( light, -3.0, 1.0, 5.0, 0.6 ) ;
lib_output_light( &light ) ;
/* output floor polygon - beige */
SET_COORD( back_color, 1.0, 0.75, 0.33 ) ;
lib_output_color(&back_color, 0.2, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0);
bvec.x = bvec.y = radius * 12.0 ;
bvec.z = -radius / 2.0 ;
SET_COORD( backg[0], bvec.x, bvec.y, bvec.z ) ;
SET_COORD( backg[1], -bvec.x, bvec.y, bvec.z ) ;
SET_COORD( backg[2], -bvec.x, -bvec.y, bvec.z ) ;
SET_COORD( backg[3], bvec.x, -bvec.y, bvec.z ) ;
lib_output_polygon( 4, backg);
/* set up object color - off white */
SET_COORD( obj_color, 1.0, 0.9, 0.7 ) ;
lib_output_color(&obj_color, 0.1, 0.6, 0.7, 10.0, 0.0, 0.0, 0.0);
/* create set of spawned points */
create_objset() ;
/* compute and output object */
SET_COORD4( center_pt, 0.0, 0.0, 0.0, radius / 2.0 ) ;
SET_COORD4( direction, 0.0, 0.0, 1.0, 1.0/3.0 ) ;
output_objset(SIZE_FACTOR, ¢er_pt, &direction ) ;
}